Design patterns help one to write code cleanly and flexibly. It is popular these days because the size of the code is becoming large and clunky to a complicated state.
Design patterns attracted its attention after the book Design Patterns: Elements of Reusable Object-Oriented Software was published in 1994 by the so-called “Gang of Four” (frequently abbreviated as “GoF”). It went even more popular after Head First Design Patterns was released in 2009 as people start noticing how common patterns helps writing clean code.
We are likely already familiar with a few well-known design patterns. Some are quite popular and some not so much. Generally, most of these patterns themselves fall in one of three general categories:
Three categories are simply guidelines. We should not restrict ourselves to these categories. There isn’t a strict pattern to apply to write a clean code. You can always come up with a new pattern that would express your code more readable and flexible in a way people will appreciate.
Here I would like to spare some time and share the top five most-seen design patterns I came across. I noticed them a couple of times in the industry and I believe there are benefits associated with each one when used right.
This behavioural design pattern selects the algorithm at runtime through composition. You can toss in the actual object of operation confined by a generic interface you wish to execute and let the operator handle it and run it. The idea is quite simple and it makes your code simple. This pattern is similar to the decorator pattern in terms of how objects delegate from one to another (composite pattern). However, the purpose is different. The strategy pattern focuses on executing a set of concrete operations whereas the decorator pattern focuses on decorating an object by delegation.
I love the creational design pattern because the pattern helps organize and structures how a set of objects should be defined rather than explicitly defining each object individually. The factory pattern could govern how an object should be created not just at compile time but also at runtime based on factors. Examples of factors can be operating systems, different data types, or input parameters. You can think of it as a black-box, an abstracted factory that creates an object based on your need. The static factory is similar but we abandon the needs for the runtime creation. There are several reasons people want you to use it. However, I frequently use it for one reason: it makes your code much more comprehensible that is readable.
The builder design pattern is quite useful in a situation where objects have many constructor parameters that may otherwise require developers to generate overrides or multiple constructors to create an object. The builder pattern is responsible for creating an object but is quite different from the factory design pattern. Factory allows creating a different type of object with a single call whereas the builder would allow assigning different traits to an object with chaining.
Decorators are a cleaner and flexible alternative to sub-classing. You can pass in an object to decorators to extend the functionality of an object without affecting other instances of the same class. This is achieved by wrapping an object of the extended class into one that extends the same class and overrides the methods whose functionality is supposed to be changed.
The facade design pattern provides the client with a simpler interface to use by putting together objects to simplify tasks. In the end, the pattern helps to make the code more readable. It works as a wrapper around the system that is being simplified. For example, say you have several tasks you do for going to a gym such as wear gym clothes, wear running shoes, prepare towels, etc. Now you can have a facade class that contains responsible for all these tasks, then you can create a simpler call called, “goToGym()”, which does all the basic things before getting to the gym. Your call now as simple as, “facade.goToGym()”.